home *** CD-ROM | disk | FTP | other *** search
/ Aminet 37 / Aminet 37 (2000)(Schatztruhe)[!][Jun 2000].iso / Aminet / comm / bbs / cit_src_AD08.lha / route.c < prev    next >
C/C++ Source or Header  |  1997-10-07  |  23KB  |  896 lines

  1. /*
  2. *       Route.C
  3. *
  4. * Some of the C86Net routemail code.
  5. */
  6. #include "ctdl.h"
  7. /*
  8. *       history
  9. *
  10. * 89Feb?? HAW  Created.
  11. */
  12. /*
  13. *                              contents
  14. *
  15. * netRouteMail()    Incoming route mail
  16. * MakeRouted()    ST route mail => C86Net
  17. */
  18. int    RouteSlot;
  19. char   RouteMailForHere;
  20. int    RouteToDirect = ERROR;
  21. static int  RWorkBuf[7];
  22. char RCount, SCount;
  23. extern int       TransProtocol;
  24. extern char      TrError;
  25. extern PROTO_TABLE Table[];
  26. extern CONFIG    cfg;
  27. extern NetBuffer netBuf, netTemp;
  28. extern NetTable  *netTab;
  29. extern FILE      *upfd, *netMisc, *netLog;
  30. extern int       thisNet;
  31. extern MessageBuffer   msgBuf;
  32. extern logBuffer logBuf;
  33. extern long ByteCount, EncCount;
  34. extern char logNetResults;
  35. extern char netDebug;
  36.  
  37. #define BAD_ROUTE "%s did not recognize %s (%s) for routed mail (%s)."
  38. #define NodeDisabled(x) (!(netTab[x].ntMemberNets & ALL_NETS))
  39. static char ParseSTRoute(char *str, char **TargetSystem, char **Domain,
  40. char **UserName);
  41. static void prStStyle(int mode, char *Name, int  (*M)(int c), char *Domain);
  42. extern int (*NetCharSource)(void);
  43. /**** These functions handle incoming route mail. ****/
  44. /*
  45. * netRouteMail() should be called in the Net Receive routines, in the big
  46. * case statement.
  47. */
  48. int RMcount = 0;                /* Incoming RoutMail count for us       */
  49. /*
  50. * netRouteMail()
  51. *
  52. * The caller has asked us to route Mail somewhere.  We determine if we want
  53. * to accept the mail or not, and if we do then we do, in fact, receive it.
  54. */
  55. void netRouteMail(struct cmd_data *cmds)
  56.   {
  57.   DOMAIN_FILE fn;
  58.   label       temp;
  59.   int   val;
  60.   char  MailForUs = FALSE, bad, dup;
  61.   extern char *APPEND_ANY, PosId;
  62.   label       Name, Id;
  63.   /*
  64.   * Do we do net routing?  At all?  From this node?  To the indicated
  65.   * node?  Even if we don't do routing per se, we should accept routed
  66.   * mail intended for this system, which is handled by RouteHere().
  67.   * Also, we do not route to disabled nodes.
  68.   */
  69.   if (cfg.BoolFlags.debug)
  70.     {
  71.     short i;
  72.     splitF(netLog, "netRouteMail(%08.8x)\n",cmds);
  73.     splitF(netLog, " struct cmd ");
  74.     splitF(netLog, "   {\n");
  75.     splitF(netLog, "   command=%x\n",cmds->command);
  76.     for(i=0;i<4;i++) splitF(netLog, "   fields[%d]:%s\n",i,cmds->fields[i]);
  77.     splitF(netLog, "   }\n");
  78.     splitF(netLog,"netBuf.nbflags.RouteFor(%x) RouteMail(%x)\n",
  79.     (int)cfg.BoolFlags.RouteMail,(int)netBuf.nbflags.RouteFor);
  80.     };
  81.   bad = (!PosId ||
  82.   (!(MailForUs = RouteHere(cmds->fields[0], cmds->fields[1],
  83.   cmds->fields[2]))) &&
  84.   (!cfg.BoolFlags.RouteMail || !netBuf.nbflags.RouteFor));
  85.   if (!bad && !MailForUs)
  86.     {
  87.     if (!FindTheNode(cmds->fields[0], ""))
  88.       {
  89.       if (strLen(cmds->fields[2]) != 0)
  90.         {
  91.         bad = ((val=DomainMailFileName(fn, cmds->fields[2],
  92.         cmds->fields[0], cmds->fields[1])) == REFUSE);
  93.  
  94.         }
  95.       else val = (MailForUs) ? OURS : LOCALROUTE;
  96.       if (!bad && val == LOCALROUTE)
  97.         {
  98.         bad = (!AcceptRoute(cmds->fields[0],"") ||
  99.         NodeDisabled(RouteSlot));
  100.  
  101.         }
  102.       /* trying to route mail without domain we don't know about? */
  103.       if (bad && strLen(cmds->fields[2]) == 0)
  104.         {
  105.         if (SystemInSecondary(cmds->fields[1], cmds->fields[2], &dup))
  106.         if (!dup)
  107.           {
  108.           bad = FALSE;
  109.           val=DomainMailFileName(fn, cmds->fields[2],
  110.           cmds->fields[0], cmds->fields[1]);
  111.  
  112.           }
  113.  
  114.         }
  115.  
  116.       }
  117.     else val = LOCALROUTE;
  118.  
  119.     }
  120.   else if (MailForUs) val = OURS;
  121.   if (bad)
  122.     {
  123.     if( logNetResults )
  124.     splitF(netLog, "Rejecting %s (%s)\n", cmds->fields[1], cmds->fields[0]);
  125.     reply(BAD, "not routing to this node for you");
  126.     return;
  127.  
  128.     }
  129.   if (val == LOCALROUTE)
  130.     {
  131.     strCpy(Name, netTemp.netName);
  132.     strCpy(Id, netTemp.netId);
  133.     FindRouteSlot();
  134.  
  135.     }
  136.   if (!MailForUs)
  137.   MailForUs = val == OURS;
  138.   if (MailForUs)
  139.     {
  140.     sPrintf(temp, "rmail.%d", RMcount++);
  141.     makeSysName(fn, temp, &cfg.netArea);
  142.  
  143.     }
  144.   else if (val == LOCALROUTE)
  145.     {
  146.     /* Ugly ugly kludge until we figure out how nbHiRouteInd is wrong */
  147.     if (netTemp.nbHiRouteInd < 0) netTemp.nbHiRouteInd = 0;
  148.     sPrintf(temp, "R%d.%d", RouteSlot, netTemp.nbHiRouteInd++);
  149.     makeSysName(fn, temp, &cfg.netArea);
  150.  
  151.     }
  152.   else
  153.     {
  154.     strCpy(Name, cmds->fields[1]);
  155.     strCpy(Id, cmds->fields[0]);
  156.  
  157.     }
  158.   if ((upfd = safeopen(fn, APPEND_ANY)) == NULL)
  159.     {
  160.     reply(BAD, "internal error");
  161.     splitF(netLog, "internal error, couldn't open %s\n", fn);
  162.     return;
  163.  
  164.     }
  165.   if (!MailForUs)
  166.     {
  167.     strCpy(Name, UseNetAlias(Name, TRUE));
  168.     fprintf(upfd, "%-20s", Id);
  169.     putc(0, upfd);
  170.     fprintf(upfd, "%-20s", Name);
  171.     putc(0, upfd);
  172.  
  173.     }
  174.   if( logNetResults )
  175.     splitF(netLog, "Route mail for %s/%s/%s.\n", cmds->fields[1],Id,Name);
  176.   if (!MailForUs)
  177.   StartEncode(putFLChar);
  178.   if (ITL_StartRecMsgs(fn, TRUE, FALSE, (!MailForUs) ? Encode : NULL)
  179.   != ITL_SUCCESS)
  180.     {
  181.     switch (val)
  182.       {
  183.       case LOCALROUTE:
  184.       netTemp.nbHiRouteInd--; break;
  185.       case DOMAINFILE:
  186.       DomainFileAddResult(cmds->fields[2], "", "", DOMAIN_FAILURE); break;
  187.  
  188.       }
  189.     MailForUs = FALSE;
  190.     splitF(netLog, "Problem receiving routemail\n");
  191.  
  192.     }
  193.   else
  194.     {
  195.     /*
  196.     * Now we note the fact that we have received routed mail.
  197.     */
  198.     switch (val)
  199.       {
  200.       case LOCALROUTE:
  201.       netTemp.nbflags.HasRouted = TRUE;
  202.       putNet(RouteSlot, &netTemp);
  203.       break;
  204.       case DOMAINFILE:
  205.       DomainFileAddResult(cmds->fields[2], Name, cmds->fields[0],
  206.       DOMAIN_SUCCESS); break;
  207.  
  208.       }
  209.  
  210.     }
  211.   if (MailForUs)
  212.   RouteMailForHere = TRUE;
  213.  
  214.   }
  215. /*
  216. * AcceptRoute()
  217. *
  218. * Will we route to the given node?
  219. */
  220. char AcceptRoute(char *id, char *name)
  221.   {
  222.   if (cfg.BoolFlags.debug)
  223.     {
  224.     splitF(netLog, "AcceptRoute(%s,%s)=%s\n",id,name
  225.     , (( netTemp.nbflags.RouteTo) ? "TRUE ":"FALSE"));
  226.     };
  227.   if (!FindTheNode(id, name)) return FALSE;
  228.   return (char)netTemp.nbflags.RouteTo;
  229.  
  230.   }
  231. /*
  232. * FindTheNode()
  233. *
  234. * This function will see if the node exists.  It will leave the index in
  235. * RouteSlot and return TRUE if found, FALSE otherwise.  This does not try
  236. * to utilize the secondary node lists.
  237. */
  238. char FindTheNode(char *id, char *name)
  239.   {
  240.   if (cfg.BoolFlags.debug)
  241.     {
  242.     splitF(netLog, "FindTheNode(%s,%s)\n",id,name);
  243.     };
  244.   if ((RouteSlot = searchNet(id, &netTemp)) != ERROR) return TRUE;
  245.   if (strLen(name) == 0) return FALSE;
  246.   if ((RouteSlot = searchNameNet(name, &netTemp)) == ERROR &&
  247.   (RouteSlot = searchNameNet(UseNetAlias(name,FALSE), &netTemp))==ERROR)
  248.   return FALSE;
  249.   return TRUE;
  250.  
  251.   }
  252. /*
  253. * FindRouteSlot()
  254. *
  255. * This function will find the slot of the routing node.  If found, netTemp
  256. * will contain the new slot, as will RouteSlot, and RouteSlot will be
  257. * returned.
  258. */
  259. int FindRouteSlot()
  260.   {
  261.   /*
  262.   * first check to see if we're the direct (final) link, either
  263.   * expressly or because the route is outdated.
  264.   */
  265.   if (!DirectRoute(&netTemp))            /* expressly?   */
  266.   getNet((RouteSlot = netTemp.nbRoute), &netTemp);
  267.   return RouteSlot;
  268.  
  269.   }
  270. /*
  271. * DirectRoute()
  272. *
  273. * This function will discover if we directly or indirectly talk to this node.
  274. */
  275. char DirectRoute(NetBuffer *n)
  276.   {
  277.   if (cfg.BoolFlags.debug)
  278.     {
  279.     splitF(netLog, "DirectRoute:nbRoute %d ", n->nbRoute );
  280.     };
  281.   return (char) (n->nbRoute == -1 ||             /* expressly?   */
  282.   n->nbRoute >= cfg.netSize ||  /* outdated? */
  283.   !netTab[n->nbRoute].ntflags.in_use ||    /* outdated?    */
  284.   netTab[n->nbRoute].ntGen != n->nbRouteGen);/* outdated?*/
  285.  
  286.   }
  287. /**** These functions handle outgoing route mail. ****/
  288. /*
  289. * RouteOut()
  290. *
  291. * This is the manager of sending outgoing route mail to the current node.  It
  292. * must handle error conditions.
  293. */
  294. void RouteOut()
  295.   {
  296.   char            abort = FALSE, failed = FALSE;
  297.   int             rover, result;
  298.   label           temp, Tid, Tname, ThisId;
  299.   SYS_FILE        fn;
  300.   extern char     *READ_ANY, OverRides;
  301.   extern AN_UNSIGNED RecBuf[];
  302.   if (netBuf.nbflags.Stadel)
  303.     {
  304.     RouteToDirect = 0;
  305.     return;
  306.  
  307.     }
  308.   normId(netBuf.netId, ThisId);
  309.   for (rover = 0; rover <= netBuf.nbHiRouteInd && !abort; rover++)
  310.     {
  311.     sPrintf(temp, "R%d.%d", thisNet, rover);
  312.     makeSysName(fn, temp, &cfg.netArea);
  313.     if ((result = SendRouteMail(fn, "", Tid, Tname, FALSE)) == GOOD_SEND)
  314.     unlink(fn);
  315.     else if (result == REFUSED_ROUTE)
  316.       {
  317.       /*
  318.       * Bad return.  Could be
  319.       *   a) system is not compatible at this level, or
  320.       *   b) system doesn't know about target
  321.       */
  322.       if (strCmpU(ThisId, Tid) == SAMESTRING)
  323.         {
  324.         if( netDebug && logNetResults )
  325.           splitF(netLog, "Rerouting to use normal mail.\n");
  326.         if (RouteToDirect == -1)
  327.           {
  328.           RouteToDirect = rover;
  329.  
  330.           }
  331.  
  332.         }
  333.       else
  334.         {
  335.         sPrintf(msgBuf.mbtext, BAD_ROUTE, netBuf.netName,
  336.         Tname, Tid, RecBuf + 1);
  337.         netResult(msgBuf.mbtext);
  338.         failed = TRUE;
  339.  
  340.         }
  341.  
  342.       }
  343.     else failed = TRUE; /* something failed, dunno what */
  344.  
  345.     }
  346.   if (!abort && !failed)
  347.     {
  348.     netBuf.nbflags.HasRouted = FALSE;
  349.     netBuf.nbHiRouteInd      = 0;
  350.  
  351.     }
  352.  
  353.   }
  354. /*
  355. * SendRouteMail()
  356. *
  357. * This function will send route mail.
  358. */
  359. char SendRouteMail(char *filename, char *domainname, char *Tid, char *Tname,
  360. char LocalCheck)
  361.   {
  362.   struct cmd_data cmds;
  363.   char work[(2 * NAMESIZE) + 10];
  364.   label ThisId;
  365.   normId(netBuf.netId, ThisId);
  366.   if ((netMisc = safeopen(filename, READ_ANY)) != NULL)
  367.     {
  368.     getMsgStr(getNetChar, cmds.fields[0], NAMESIZE);
  369.     getMsgStr(getNetChar, cmds.fields[1], NAMESIZE);
  370.     if (!normId(cmds.fields[0], Tid) || strLen(Tid) == 0)
  371.     strCpy(cmds.fields[0], "  ");
  372.     else
  373.     strCpy(cmds.fields[0], Tid);
  374.     if (LocalCheck)
  375.     if (!netBuf.nbflags.Stadel && strCmpU(Tid,ThisId) != SAMESTRING)
  376.       {
  377.       fclose(netMisc);
  378.       return REFUSED_ROUTE; /* actually, just a lie */
  379.  
  380.       }
  381.     NormStr(cmds.fields[1]);
  382.     strCpy(Tname, cmds.fields[1]);    /* reporting purposes */
  383.     strCpy(cmds.fields[2], domainname); /* just for luck        */
  384.     cmds.command = ROUTE_MAIL;
  385.     if( logNetResults )
  386.       {
  387.       if (strLen(domainname) != 0 )
  388.         splitF(netLog, "Routing mail to %s _ %s/%s/%s\n", cmds.fields[1],
  389.         domainname,
  390.         (Tid != NULL) ? Tid : "NULL", (Tname != NULL) ? Tname : "NULL" );
  391.       else
  392.         splitF(netLog, "Routing mail to %s/%s/%s\n", cmds.fields[1],
  393.         (Tid != NULL) ? Tid : "NULL", (Tname != NULL) ? Tname : "NULL" );
  394.       };
  395.     if (LocalCheck || sendNetCommand(&cmds, "Route Mail"))
  396.       {
  397.       if (LocalCheck || ITL_SendMessages())
  398.         {
  399.         StartDecode(ReadRoutedDest);
  400.         RCount = SCount = 0;
  401.         NetCharSource = ReadRouted;
  402.         sPrintf(work,
  403.         (strLen(domainname) != 0) ? "%s _ %s" : "%s%s",
  404.         cmds.fields[1], domainname);
  405.         while (getMessage(ReadRouted, TRUE, FALSE, TRUE))
  406.         if (netBuf.nbflags.Stadel)
  407.         prStStyle(1, Tname, sendITLchar, domainname);
  408.         else
  409.         prNetStyle(1, sendITLchar, TRUE, work);
  410.         NetCharSource = getNetChar;
  411.         fclose(netMisc);
  412.         if (!LocalCheck) ITL_StopSendMessages();
  413.         if (cfg.BoolFlags.debug)
  414.         splitF(netLog, "Encoded %ld bytes, sent %ld bytes.\n", EncCount, ByteCount);
  415.         if (TrError == TRAN_SUCCESS)
  416.         return GOOD_SEND;
  417.         else
  418.         return UNKNOWN_ERROR;
  419.  
  420.         }
  421.  
  422.       }
  423.     else
  424.       {
  425.       if( logNetResults && netDebug )splitF(netLog, "RouteMail rejection!\n");
  426.       fclose(netMisc);
  427.       return REFUSED_ROUTE;
  428.  
  429.       }
  430.  
  431.     }
  432.   return NO_SUCH_FILE;
  433.  
  434.   }
  435. /*
  436. * AdjustRoute()
  437. *
  438. * This function adjusts the routed files names.  Basically, it finds "holes"
  439. * in the sequence of numerical filenames and adjusts names to fill those
  440. * holes.
  441. */
  442. void AdjustRoute()
  443.   {
  444.   int      rover, next;
  445.   label    temp;
  446.   SYS_FILE fn, fn2;
  447.   rover = 0;
  448.   while (rover < netBuf.nbHiRouteInd)
  449.     {
  450.     sPrintf(temp, "R%d.%d", thisNet, rover);
  451.     makeSysName(fn, temp, &cfg.netArea);
  452.     if (access(fn, 0) != 0)
  453.       {
  454.       next = rover + 1;
  455.       do
  456.         {
  457.         sPrintf(temp, "R%d.%d", thisNet, next++);
  458.         makeSysName(fn2, temp, &cfg.netArea);
  459.  
  460.         }
  461.       while (access(fn2, 0) != 0 && next <= netBuf.nbHiRouteInd);
  462.       if (access(fn2, 0) != 0)
  463.         {
  464.         if (rover == 0)
  465.           {
  466.           netBuf.nbflags.HasRouted = FALSE;
  467.           netBuf.nbHiRouteInd = 0;
  468.  
  469.           }
  470.         else
  471.         netBuf.nbHiRouteInd = rover - 1;
  472.         break;
  473.  
  474.         }
  475.       else
  476.         {
  477.         rename(fn2, fn);
  478.         rover++;
  479.  
  480.         }
  481.  
  482.       }
  483.     rover++;
  484.  
  485.     }
  486.   /* I think* this is right. */
  487.   if (rover == 0)
  488.     {
  489.     netBuf.nbflags.HasRouted = FALSE;
  490.     netBuf.nbHiRouteInd = 0;
  491.  
  492.     }
  493.  
  494.   }
  495. /*
  496. * SendRoutedAsLocal()
  497. *
  498. * This function will reroute route mail to use local mail.
  499. */
  500. int SendRoutedAsLocal()
  501.   {
  502.   label ThisId, Tid, Name, temp;
  503.   SYS_FILE fn;
  504.   char finished = FALSE;
  505.   int  toReturn = 0, result;
  506.   extern char OverRides;
  507.   if (RouteToDirect == -1 && !netBuf.nbflags.Stadel) return 0;
  508.   normId(netBuf.netId, ThisId);
  509.   do
  510.     {
  511.     sPrintf(temp, "R%d.%d", thisNet, RouteToDirect++);
  512.     makeSysName(fn, temp, &cfg.netArea);
  513.     if ((result = SendRouteMail(fn, "", Tid, Name, TRUE)) == GOOD_SEND)
  514.       {
  515.       unlink(fn);
  516.       toReturn++;
  517.  
  518.       }
  519.     else if (result == NO_SUCH_FILE)
  520.     finished = TRUE;
  521.  
  522.     }
  523.   while (!finished);
  524.   return toReturn;
  525.  
  526.   }
  527. /*
  528. * ReadRoutedDest()
  529. *
  530. * This work function will help read encrypted (style 1) data.
  531. */
  532. int ReadRoutedDest(int c)
  533.   {
  534.   RWorkBuf[RCount++] = c;
  535.   return TRUE;
  536.  
  537.   }
  538. /*
  539. * ReadRouted()
  540. *
  541. * This function will read a routed char for getMessage().
  542. */
  543. int ReadRouted()
  544.   {
  545.   int c;
  546.   if (RCount != SCount)
  547.   return RWorkBuf[SCount++];
  548.   RCount = SCount = 0;
  549.   while (SCount == RCount && (c = fgetc(netMisc)) != EOF)
  550.   Decode(c);
  551.   if (RCount != SCount)
  552.   return RWorkBuf[SCount++];
  553.   if (c == EOF) StopDecode();
  554.   if (RCount != SCount)
  555.   return RWorkBuf[SCount++];
  556.   return -1;
  557.  
  558.   }
  559. /*
  560. * prStStyle()
  561. *
  562. * This is used to handle problems inherent in STadel mail routing.
  563. */
  564. static void prStStyle(int mode, char *Name, int (*M)(int c), char *Domain)
  565.   {
  566.   char work[4 * NAMESIZE];
  567.   extern SListBase MailForward;
  568.   ForwardMail *address;
  569.   if (strCmpU(netBuf.netName, Name) != SAMESTRING)
  570.     {
  571.     if (!msgBuf.mbaddr[0])
  572.       {
  573.       if ((address = SearchList(&MailForward, msgBuf.mbto)) != NULL)
  574.       strCpy(msgBuf.mbto, address->Alias);
  575.  
  576.       }
  577.     if (strLen(Domain) != 0)
  578.       {
  579.       sPrintf(work, "%s.%s!%s", Name, Domain, msgBuf.mbto);
  580.       strCpy(msgBuf.mbto, work);
  581.  
  582.       }
  583.     else
  584.       {
  585.       sPrintf(work, "%s!%s", netBuf.netName, Name);
  586.       NormStr(work);  /* shave off trailing blanks... */
  587.       sPrintf(lbyte(work), "!%s", msgBuf.mbto);
  588.       strCpy(msgBuf.mbto, work);
  589.  
  590.       }
  591.  
  592.     }
  593.   if (strLen(msgBuf.mbdomain) != 0 && strLen(msgBuf.mboname) != 0)
  594.     {
  595.     sPrintf(work, "%s.%s!%s", msgBuf.mboname, msgBuf.mbdomain,
  596.     msgBuf.mbauth);
  597.     strCpy(msgBuf.mbauth, work);
  598.  
  599.     }
  600.   prNetStyle(mode, M, TRUE, Name);
  601.  
  602.   }
  603. /*
  604. * MakeRouted()
  605. *
  606. * This function transforms an ST route mail message into C86Net.
  607. *
  608. * Format: <system>![<system>!...]<username> ... I hope!
  609. *
  610. * There should also be allowances for using domain addresses.
  611. */
  612. void MakeRouted()
  613.   {
  614.   char  dup, *UserName, *TargetSystem, *Domain, work[(2 * NAMESIZE) + 6];
  615.   label TheDomain, System;
  616.   int   Slot, val = ERROR;
  617.   /*
  618.   * We parse the author field (which is the route back to the
  619.   * author, form [<system>!...]<home system>!<username>.  TargetSystem
  620.   * should have the name of the home system, UserName is obvious.  If
  621.   * TargetSystem contains a '.', then the address is domain-defined.
  622.   */
  623.   printf("MakeRouted\n");
  624.   if (ParseSTRoute(msgBuf.mbauth, &TargetSystem, &Domain, &UserName))
  625.     {
  626.     strCpy(msgBuf.mboname, TargetSystem);
  627.     msgBuf.mborig[0] = 0;
  628.     /*
  629.     * Is this domain mail?  If so, just set the domain stuff up
  630.     * correctly and don't worry whether we know this guy personally.
  631.     */
  632.     if (Domain != NULL)
  633.       {
  634.       strCpy(msgBuf.mbdomain, Domain);
  635.       strCpy(msgBuf.mboname, TargetSystem);
  636.  
  637.       }
  638.     else
  639.       {
  640.       /*
  641.       * So now we find out if we know the name.  If we do, netTemp will
  642.       * contain the appropriate net data.
  643.       */
  644.       if (IdStName(msgBuf.mboname) != ERROR)
  645.       strCpy(msgBuf.mborig, netTemp.netId);
  646.       strCpy(msgBuf.mbauth, UserName);
  647.  
  648.       }
  649.  
  650.     }
  651.   /*
  652.   * Now we parse the To field, which is potentially in the same format
  653.   * as the Author field, above.  TargetSystem is the final target,
  654.   * User name is the recipient.  If, for some reason, no target system
  655.   * is specified, we assume we are the target.
  656.   */
  657.   if (!ParseSTRoute(msgBuf.mbto, &TargetSystem, &Domain, &UserName))
  658.     {
  659.     TargetSystem = cfg.nodeName + cfg.codeBuf;
  660.     UserName = msgBuf.mbto;
  661.  
  662.     }
  663.   if( logNetResults )
  664.   if (Domain == NULL)
  665.   splitF(netLog, "Routing mail to %s.\n", TargetSystem);
  666.   else
  667.   splitF(netLog, "Routing mail to %s _ %s.\n", TargetSystem, Domain);
  668.   /* If we are the target, just deliver the damn message and get out. */
  669.   if (RouteHere("", TargetSystem, Domain))
  670.     {
  671.     strCpy(msgBuf.mbto, UserName);
  672.     putMessage(&logBuf);
  673.     return;
  674.  
  675.     }
  676.   /*
  677.   * OK, so the Mail is not for our system.  Find out whom and put in
  678.   * routing.
  679.   */
  680.   /*
  681.   * If we can't figure out the target system, dump it and die.
  682.   */
  683.   if ((Slot = IdStName(TargetSystem)) == ERROR)
  684.     {
  685.     /* search secondary list now */
  686.     if (Domain != NULL && strLen(Domain) != 0)
  687.     sPrintf(work, "%s _ %s", TargetSystem, Domain);
  688.     else
  689.     strCpy(work, TargetSystem);
  690.     if (!SystemInSecondary(work, TheDomain, &dup) || dup)
  691.       {
  692.       strCpy(System, TargetSystem);
  693.       strCpy(msgBuf.mbto, UserName);
  694.       if( logNetResults && netDebug)splitF(netLog, "Could not identify target '%s'.\n", TargetSystem);
  695.       netMailOut(TRUE, System, "unknown", FALSE, 0);
  696.       return ;
  697.  
  698.       }
  699.     Domain = TheDomain;
  700.     TargetSystem = work;
  701.  
  702.     }
  703.   else TargetSystem = netTemp.netName;
  704.   /* We know where, now to put it all together. */
  705.   strCpy(msgBuf.mbto, UserName);
  706.   if (!cfg.BoolFlags.RouteMail ||
  707.   (val == LOCALROUTE && !netBuf.nbflags.RouteFor))
  708.     {
  709.     sPrintf(msgBuf.mbtext, "System %s tried to illegally route via you.\n",
  710.     netBuf.netName);
  711.     netResult(msgBuf.mbtext);
  712.     return ;
  713.  
  714.     }
  715.   #ifdef WANTED
  716.   if (val == LOCALROUTE && !netTemp.nbflags.RouteTo)
  717.     {
  718.     sPrintf(msgBuf.mbtext, "System %s tried to route to %s.\n",
  719.     netBuf.netName, netTemp.netName);
  720.     netResult(msgBuf.mbtext);
  721.     return ;
  722.  
  723.     }
  724.   #endif
  725.   if (Domain != NULL)
  726.   netMailOut((Domain != NULL), TargetSystem, Domain, FALSE, Slot);
  727.   if (val == LOCALROUTE && thisNet == Slot)
  728.     {
  729.     /* kludge fix if system is routing back to itself */
  730.     netBuf.nbflags.HasRouted = netTemp.nbflags.HasRouted;
  731.     netBuf.nbHiRouteInd++;
  732.  
  733.     }
  734.  
  735.   }
  736. /*
  737. * IdStName()
  738. *
  739. * This function will find the STadel route name in our lists. It leaves
  740. * netTemp with the net element which matched, and returns the
  741. * slot number.  It does limited translations for underscores.
  742. */
  743. int IdStName(char *name)
  744.   {
  745.   int Slot;
  746.   char *Alias;
  747.   int StSearch(char *name);
  748.   while ((Alias = strchr(name, ' ')) != NULL)
  749.   *Alias = '_';
  750.   if ((Slot = StSearch(name)) != ERROR) return Slot;
  751.   if ((Alias = strchr(name, '_')) != NULL)
  752.     {
  753.     while ((Alias = strchr(name, '_')) != NULL)
  754.     *Alias = ' ';
  755.     Slot = StSearch(name);
  756.  
  757.     }
  758.   return Slot;
  759.  
  760.   }
  761. /*
  762. * StSearch()
  763. *
  764. * This function will search the ctdlnet for the given node by name.  If the
  765. * initial search fails, then the alias list is searched for an alias and
  766. * another attempt is made using the result.
  767. */
  768. int StSearch(char *name)
  769.   {
  770.   int Slot;
  771.   if ((Slot = searchNameNet(name, &netTemp)) != ERROR)
  772.   return Slot;
  773.   if ((Slot = searchNameNet(UseNetAlias(name, FALSE), &netTemp)) != ERROR)
  774.   return Slot;
  775.   return ERROR;
  776.  
  777.   }
  778. static label SearchResult;
  779. static char  *SearchTarget, GetAlias;
  780. /*
  781. * UseNetAlias()
  782. *
  783. * This will find a usenet alias or the converse from ALIASES.SYS.
  784. */
  785. char *UseNetAlias(char *Name, char FindAlias)
  786.   {
  787.   void *EatTrans();
  788.   SListBase Dummy =
  789.     {
  790.     NULL, NULL, NULL, NULL, EatTrans
  791.  
  792.     };
  793.   SYS_FILE fn;
  794.   char *c, *WorkName;
  795.   WorkName = strdup(Name);  /* use a work buffer */
  796.   SearchResult[0] = 0;
  797.   SearchTarget = WorkName;
  798.   if (!FindAlias) while ((c = strchr(WorkName, ' ')) != NULL) *c = '_';
  799.   makeSysName(fn, "aliases.sys", &cfg.roomArea);
  800.   GetAlias = FindAlias;
  801.   MakeList(&Dummy, fn, NULL); /* CHEAT!  WHEEEEEE! */
  802.   free(WorkName);
  803.   if (strLen(SearchResult) == 0) return Name;
  804.   if (FindAlias) while ((c = strchr(SearchResult, '_')) != NULL) *c = ' ';
  805.   return SearchResult;
  806.  
  807.   }
  808. /*
  809. * EatTrans()
  810. *
  811. * This digests a line of input from the ALIASES.SYS file, and, depending
  812. * on the value of the GetAlias variable, checks the variable SearchTarget
  813. * against either the alias or the name found on the input line.  If a
  814. * match is found the other field value is then copied into SearchResult,
  815. * a global variable.  Since this is only called from MakeList(), and we're
  816. * not really making a list, this always returns NULL.  We use MakeList()
  817. * just as a cheat.
  818. */
  819. void *EatTrans(char *line)
  820.   {
  821.   char *c;
  822.   NormStr(line);
  823.   if ((c = strchr(line, ' ')) != NULL)
  824.     {
  825.     *c = 0;
  826.     if (GetAlias)
  827.       {
  828.       /* check second field */
  829.       if (strCmpU(c + 1, SearchTarget) == SAMESTRING)
  830.         {
  831.         strCpy(SearchResult, line);
  832.  
  833.         }
  834.  
  835.       }
  836.     else
  837.       {
  838.       /* check first field */
  839.       if (strCmpU(line, SearchTarget) == SAMESTRING)
  840.         {
  841.         strCpy(SearchResult, c + 1);
  842.  
  843.         }
  844.  
  845.       }
  846.  
  847.     }
  848.   return NULL;
  849.  
  850.   }
  851. /*
  852. * ParseSTRoute()
  853. *
  854. * This parses a ST route path for recipient and target.  It can handle
  855. * domain specifications, too.
  856. *
  857. * RETURNS:
  858. *
  859. *  o FALSE if this does not appear to have any STadel routing information
  860. *    information in the field.
  861. *
  862. *  o TRUE if there did seem to be information and it was parsed out.
  863. *
  864. * str - the field containing the unparsed information.  This will be
  865. * changed by this function.
  866. *
  867. * TargetSystem - will contain the target system name after parsing.
  868. *
  869. * Domain - will contain the domain name after parsing.
  870. *
  871. * UserName - will contain the user's name after parsing.
  872. */
  873. static char ParseSTRoute(char *str, char **TargetSystem, char **Domain,
  874. char **UserName)
  875.   {
  876.   if ((*UserName = strrchr(str, '!')) == NULL)
  877.     {
  878.     return FALSE;
  879.  
  880.     }
  881.   **UserName = 0; /* now recipient's name does not interfere */
  882.   (*UserName)++;    /* with system target */
  883.   if ((*TargetSystem = strrchr(str, '!')) == NULL)
  884.   *TargetSystem = str;
  885.   else
  886.   (*TargetSystem)++;    /* gets us past our search target */
  887.   if ((*Domain = strrchr(str, '.')) != NULL)
  888.     {
  889.     **Domain = 0;
  890.     (*Domain)++;    /* with system target */
  891.  
  892.     }
  893.   return TRUE;
  894.  
  895.   }
  896.